import other from '/@/utils/other';
import request from '/@/utils/request';
import { fetchEventSource } from '@microsoft/fetch-event-source';
import { Session } from '/@/utils/storage';

export interface IOrchestrationScope {
	id?: string;
	username: string;
}

export enum EOrchestrationType {
	WORK_FLOW = 'WORK_FLOW',
	SIMPLE = 'SIMPLE',
}

export interface IOrchestrationItem {
	id?: string;
	name?: string;
	type?: EOrchestrationType;
	description?: string;
	isPublic?: boolean;
	publicAddress?: string;
	apiAddress?: string;
	apiBaseUrl?: string;

	fullScreenUrl?: string;
	fixedUrl?: string;

	questionLimit?: number;
	whiteListEnable?: boolean;
	whiteList?: string;
	showSource?: boolean;

	modelId?: string;

	createBy?: string;
	createTime?: string;
	updateTime?: string;

	modelSetting?: {
		prompt?: string;
		system?: string;
		noReferencesPrompt?: string;
	};
	dialogueNumber?: number;
	datasetIdList?: any[];
	datasetSetting?: {
		searchMode?: string;
		similarity?: number;
		topN?: number;
		maxParagraphCharNumber?: number;
		noReferencesSetting?: {
			status?: string;
			designatedAnswer?: string;
		};
	};
	problemOptimizationPrompt?: string;
	problemOptimization?: boolean;
	prologue?: string;
	sttModelEnable?: boolean;
	sttModelId?: string;
	ttsModelEnable?: boolean;
	ttsType?: string;
	ttsModelId?: string;
	ttsModelParamsSetting?: {};
	fileUploadSetting?: {
		audio?: boolean;
		image?: boolean;
		video?: boolean;
		document?: boolean;
		maxFiles?: number;
		fileLimit?: number;
	};
	disclaimerValue?: string;
}

export interface IOrchestrationAPIKey {
	id?: string;
	allowCrossDomain?: boolean;
	application?: string;
	createTime?: string;
	crossDomainList?: string;
	isActive?: boolean;
	secretKey?: string;
	updateTime?: string;
}

export function fetchList(query?: Object) {
	return request({
		url: '/knowledge/aiFlow/page',
		method: 'get',
		params: query,
	});
}

export function addObj(obj?: Object) {
	return request({
		url: '/knowledge/aiFlow',
		method: 'post',
		data: obj,
	});
}

export function getObj(id?: string) {
	return request({
		url: '/knowledge/aiFlow/' + id,
		method: 'get',
	});
}

export function delObjs(ids?: Object) {
	return request({
		url: '/knowledge/aiFlow',
		method: 'delete',
		data: ids,
	});
}

export function putObj(obj?: Object) {
	return request({
		url: '/knowledge/aiFlow',
		method: 'put',
		data: obj,
	});
}

export function exportFlow(id: string, name: string) {
	return other.downBlobFile(`/knowledge/aiFlow/export/${id}`, {}, `${name}.dsl`);
}

export function copyFlow(id: string) {
	return request.post(`/knowledge/aiFlow/copy/${id}`);
}

export function importFlow(data: FormData) {
	return request.post(`/knowledge/aiFlow/import`, data);
}

export interface IOrchestrationAPIKey {
	id?: string;
	allowCrossDomain?: boolean;
	application?: string;
	createTime?: string;
	crossDomainList?: string;
	isActive?: boolean;
	secretKey?: string;
	updateTime?: string;
}

/**
 * @description  : 编排 发起导入
 * @return        {any}
 */
export async function orchestrationImportContent(data: FormData) {
	return request.post(`/knowledge/orchestration/import/content`, data);
}

/**
 * @description  : 编排 发起导出
 * @return        {any}
 */
export async function orchestrationExportContent(id: string, name: string) {
	return other.downBlobFile(`/knowledge/orchestration/export/content/${id}`, {}, name);
}

/**
 * @description  : 复制 编排
 * @param         {string} originId
 * @param         {IOrchestrationItem} data
 * @return        {any}
 */
export async function orchestrationCopy(originId: string, data: IOrchestrationItem) {
	return request.post(`/knowledge/orchestration/copy/${originId}`, data);
}

/**
 * @description  : 获取 编排 详情
 * @param         {string} id
 * @return        {any}
 */
export async function fetchOrchestrationInfo(id: string) {
	return request.get(`/knowledge/orchestration/info/${id}`);
}

export async function fetchChartRecord(id: string, data: { startTime: string; endTime: string }) {
	return request.get(`/knowledge/orchestration/chart/record/${id}`, { params: data });
}

export async function fetchOrchestrationAPIKeyList(data: { id: string }) {
	return request.get(`/knowledge/orchestration/apikey/${data.id}`);
}

export async function orchestrationAPIKeyUpdate(data: any) {
	return request.put(`/knowledge/orchestration/apikey/update`, data);
}

export async function orchestrationAPIKeyAdd(id: string) {
	return request.post(`/knowledge/orchestration/apikey/${id}/add`);
}

export async function orchestrationAPIKeyRemove(id: string) {
	return request.delete(`/knowledge/orchestration/apikey/${id}/delete`);
}

/**
 * @description  : 获取模型的参数设置
 * @param         {string} orchestrationId
 * @param         {string} modelId
 * @return        {any}
 */
export async function fetchModelParamsForm(orchestrationId: string, modelId: string) {
	return request.get(`/knowledge/orchestration/${orchestrationId}/modelParamsForm/${modelId}`);
}

/**
 * @description  : 播放测试文本
 * @param         {string} id
 * @param         {any} data
 * @return        {any}
 */
export function playDemoText(id: string, data: any) {
	return request.post(`/knowledge/orchestration/playDemoText/${id}`, data, {
		responseType: 'blob',
	});
}

/**
 * @description  : 文件上传
 * @param         {String} application_id
 * @param         {String} chat_id
 * @param         {any} data
 * @return        {any}
 */
export function chatUploadFile(application_id: string, chat_id: String, data: any) {
	return request.post(`/knowledge/orchestration/uploadFile/${application_id}/${chat_id}`, data);
}

/**
 * @description  : 上传录音文件
 * @param         {string} application_id
 * @param         {any} data
 * @return        {any}
 */
export function chatPostSpeechToText(application_id: string, data: any) {
	return request.post(`/knowledge/orchestration/chatPostSpeechToText/${application_id}`, data);
}

export interface FlowExecutionResult {
	nodes: any[];
	executed: boolean;
	result: any;
	duration: number;
	error?: string;
	totalTokens?: number;
}

export interface FlowExecutionEvent {
	type: 'start' | 'progress' | 'complete' | 'error' | 'chat_message';
	nodeId?: string;
	nodeName?: string;
	data?: any;
	progress?: number;
	error?: string;
	result?: FlowExecutionResult;
	content?: string;
	tokens?: number; // 添加 tokens 字段
	duration?: number; // 添加 duration 字段
	nodes?: Array<any>; // 添加 nodes 字段
	isStreaming?: boolean;
}

export interface FlowExecutionCallbacks {
	onStart?: () => void;
	onProgress?: (event: FlowExecutionEvent) => void;
	onComplete?: (result: FlowExecutionResult) => void;
	onError?: (error: string) => void;
	onChatMessage?: (content: string, isComplete: boolean, tokens?: number, duration?: number, nodes?: Array<any>) => void;
}

export function executeFlow(data: { id: string; params: any; envs: any; stream?: boolean }) {
	return request.post(`/knowledge/aiFlow/execute`, data, {
		timeout: 300000 // 设置超时时间为300秒 (300000毫秒)
	});
}

/**
 * 使用SSE执行工作流，提供实时执行状态更新
 * @param data 执行参数
 * @param callbacks 回调函数
 * @returns Promise<FlowExecutionResult>
 */
export async function executeFlowSSE(
	data: { id: string; params: any; envs: any; stream?: boolean },
	callbacks?: FlowExecutionCallbacks
): Promise<FlowExecutionResult> {
	const token = Session.getToken();
	const tenant = Session.getTenant();
	
	return new Promise<FlowExecutionResult>((resolve, reject) => {
		let controller: AbortController | null = new AbortController();
		let result: FlowExecutionResult | null = null;

		const cleanup = () => {
			if (controller) {
				controller.abort();
				controller = null;
			}
		};

		// 解析SSE返回的数据
		const parseSSEResponse = (eventData: string) => {
			try {
				const parsed = JSON.parse(eventData);
				
				// 处理聊天格式的数据: {"data":{"content":"...", "tokens": 123, "duration": 22986, "nodes": [...]}}
				if (parsed.data && parsed.data.content !== undefined) {
					return {
						type: 'chat_message',
						content: parsed.data.content,
						tokens: parsed.data.tokens, // 添加 tokens 字段
						duration: parsed.data.duration, // 添加 duration 字段
						nodes: parsed.data.nodes, // 添加 nodes 字段
						isStreaming: true
					} as FlowExecutionEvent;
				}
				
				// 处理标准的FlowExecutionEvent格式
				return parsed as FlowExecutionEvent;
			} catch (e) {
				return null;
			}
		};

		const fetchOptions = {
			method: 'POST',
			headers: {
				'Content-Type': 'application/json',
				Authorization: `Bearer ${token}`,
				'TENANT-ID': tenant,
			},
			body: JSON.stringify(data),
			signal: controller?.signal,
			async onopen(response: Response) {
				if (response.ok && response.headers.get('content-type')?.includes('text/event-stream')) {
					callbacks?.onStart?.();
					return;
				}
				throw new Error(`Failed to connect: ${response.status} ${response.statusText}`);
			},
			onmessage(event: { data: string }) {
				const parsed = parseSSEResponse(event.data);
				if (!parsed) return;

				switch (parsed.type) {
					case 'start':
						callbacks?.onStart?.();
						break;
					case 'progress':
						callbacks?.onProgress?.(parsed);
						break;
					case 'chat_message':
						// 处理聊天消息流
						if (parsed.content !== undefined) {
												// 检查是否收到完成标记
					if (parsed.content === '[DONE]') {
						// 标记聊天消息完成并关闭连接，传递 tokens、duration 和 nodes 信息
						callbacks?.onChatMessage?.('', true, parsed.tokens, parsed.duration, parsed.nodes);
						cleanup();
						// 如果没有正式的结果，创建一个默认结果
						if (!result) {
							result = {
								nodes: parsed.nodes || [],
								executed: true,
								result: {},
								duration: parsed.duration || 0,
								totalTokens: parsed.tokens || 0
							};
							callbacks?.onComplete?.(result);
							resolve(result);
						}
						return;
					}
					callbacks?.onChatMessage?.(parsed.content, false, parsed.tokens, parsed.duration, parsed.nodes);
						}
						break;
					case 'complete':
						if (parsed.result) {
							result = parsed.result;
							callbacks?.onComplete?.(parsed.result);
							resolve(parsed.result);
						}
						break;
					case 'error':
						const errorMsg = parsed.error || 'Unknown error occurred';
						callbacks?.onError?.(errorMsg);
						reject(new Error(errorMsg));
						break;
				}
			},
			onclose() {
				// 连接关闭时，如果有未完成的聊天消息，标记为完成
				if (callbacks?.onChatMessage) {
					callbacks.onChatMessage('', true);
				}
				cleanup();
			},
			onerror(error: Error) {
				cleanup();
				const errorMsg = error.message || 'Connection error';
				callbacks?.onError?.(errorMsg);
				// 抛出错误以停止自动重试
				throw error;
			},
		};

		// 启动SSE连接，添加重试控制
		fetchEventSource(`${request.defaults.baseURL}${other.adaptationUrl('/knowledge/aiFlow/execute')}`, {
			...fetchOptions,
			// 禁用自动重试以避免重复发起请求
			openWhenHidden: false, // 页面隐藏时不重试
		})
			.catch((error) => {
				cleanup();
				if (error.name === 'AbortError') {
					reject(new Error('Request was cancelled'));
				} else {
					reject(error);
				}
			});

		// 返回清理函数以便外部可以取消请求
		return cleanup;
	});
}

/**
 * 取消SSE工作流执行
 * @param executionId 执行ID
 */
export async function cancelFlowExecution(executionId: string) {
	return request.post(`/knowledge/aiFlow/cancel/${executionId}`);
}

/**
 * 专为聊天格式设计的SSE工作流执行函数
 * 处理 {"data":{"content":"..."}} 格式的流式响应
 * @param data 执行参数
 * @param callbacks 回调函数
 * @returns {Promise<{chatMessage: string, result: any}> & {cleanup: () => void}} 包含cleanup函数的Promise
 */
export function executeFlowSSEWithChat(
	data: { id: string; conversationId: string; params: any; envs: any; stream?: boolean },
	callbacks?: FlowExecutionCallbacks
): Promise<{chatMessage: string, result: any}> & {cleanup: () => void} {
	const token = Session.getToken();
	const tenant = Session.getTenant();
	
	let controller: AbortController | null = new AbortController();
	let isManuallyAborted = false; // 添加手动取消标记
	
	const cleanup = () => {
		if (controller && !isManuallyAborted) {
			isManuallyAborted = true; // 标记为手动取消
			controller.abort();
			controller = null;
		}
	};
	
	const promise = new Promise<{chatMessage: string, result: any}>((resolve, reject) => {
		let chatMessageContent = '';
		let hasReceivedData = false;

		const fetchOptions = {
			method: 'POST',
			headers: {
				'Content-Type': 'application/json',
				Authorization: `Bearer ${token}`,
				'TENANT-ID': tenant,
			},
			body: JSON.stringify(data),
			signal: controller?.signal,
			async onopen(response: Response) {
				if (response.ok && response.headers.get('content-type')?.includes('text/event-stream')) {
					callbacks?.onStart?.();
					return;
				}
				throw new Error(`Failed to connect: ${response.status} ${response.statusText}`);
			},
			onmessage(event: { data: string }) {
				try {
					const parsed = JSON.parse(event.data);
					
					// 处理聊天格式的数据: {"data":{"content":"...", "tokens": 123, "duration": 22986}}
					if (parsed.data && parsed.data.content !== undefined) {
						hasReceivedData = true;
						
										// 检查是否收到完成标记
				if (parsed.data.content === '[DONE]') {
					const result = {
						chatMessage: chatMessageContent,
						result: {
							nodes: parsed.data.nodes || [],
							executed: true,
							result: {},
							duration: parsed.data.duration || 0,
							totalTokens: parsed.data.tokens || 0
						}
					};
					callbacks?.onChatMessage?.('', true, parsed.data.tokens, parsed.data.duration, parsed.data.nodes); // 标记聊天消息完成，传递 tokens、duration 和 nodes
					callbacks?.onComplete?.(result.result);
					cleanup();
					resolve(result);
					return;
				}
				
				chatMessageContent += parsed.data.content;
				callbacks?.onChatMessage?.(parsed.data.content, false, parsed.data.tokens, parsed.data.duration, parsed.data.nodes);
						return;
					}
					
					// 处理其他类型的事件
					if (parsed.type) {
						switch (parsed.type) {
							case 'start':
								callbacks?.onStart?.();
								break;
							case 'progress':
								callbacks?.onProgress?.(parsed);
								break;
							case 'complete':
								const result = {
									chatMessage: chatMessageContent,
									result: parsed.result || {}
								};
								callbacks?.onChatMessage?.('', true); // 标记聊天消息完成
								callbacks?.onComplete?.(parsed.result);
								resolve(result);
								break;
							case 'error':
								const errorMsg = parsed.error || 'Unknown error occurred';
								callbacks?.onError?.(errorMsg);
								reject(new Error(errorMsg));
								break;
						}
					}
				} catch (e) {
					// 忽略无法解析的数据
				}
			},
			onclose() {
				// 连接关闭时，如果有数据但没有收到完成事件，自动完成
				if (hasReceivedData) {
					const result = {
						chatMessage: chatMessageContent,
						result: {}
					};
					callbacks?.onChatMessage?.('', true);
					resolve(result);
				}
				cleanup();
			},
			onerror(error: Error) {
				cleanup();
				const errorMsg = error.message || 'Connection error';
				callbacks?.onError?.(errorMsg);
				// 如果不是手动取消，则报告错误；否则阻止自动重试
				if (!isManuallyAborted) {
					reject(new Error(errorMsg));
				}
				// 抛出错误以停止自动重试
				throw error;
			},
		};

		// 启动SSE连接，添加重试控制
		fetchEventSource(`${request.defaults.baseURL}${other.adaptationUrl('/knowledge/aiFlow/execute')}`, {
			...fetchOptions,
			// 禁用自动重试以避免重复发起请求
			openWhenHidden: false, // 页面隐藏时不重试
		})
			.catch((error) => {
				cleanup();
				if (error.name === 'AbortError') {
					// 如果是手动取消，不报告错误
					if (!isManuallyAborted) {
						reject(new Error('Request was cancelled'));
					}
				} else {
					reject(error);
				}
			});
	});
	
	// 返回带有cleanup方法的Promise
	return Object.assign(promise, { cleanup });
}